package com.diamondsys.embrapa;

import com.diamondsys.embrapa.util.JsfUtil;
import com.diamondsys.embrapa.util.JsfUtil.PersistAction;
import java.io.IOException;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import org.primefaces.event.FileUploadEvent;

@Named("sacController")
@SessionScoped
public class SacController implements Serializable {

    @EJB
    private com.diamondsys.embrapa.SacFacade ejbFacade;
    private List<Sac> items = null;
    private Sac selected;
    private TbInst selectedCliente;
    private Date dateFrom;
    private Date dateTo;

    public Date getDateFrom() {
        return dateFrom;
    }

    public void setDateFrom(Date dateFrom) {
        this.dateFrom = dateFrom;
    }

    public Date getDateTo() {
        return dateTo;
    }

    public void setDateTo(Date dateTo) {
        this.dateTo = dateTo;
    }
    
    public boolean filterByDate(Object value, Object filter, Locale locale) {
        boolean ret=true;
        
        String filterText = (value == null) ? null : value.toString().trim();
        if (filterText == null || filterText.isEmpty()) {
            return true;
        }
        
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        Date filterDate;

        try {
            filterDate = df.parse(filterText);
            if (dateFrom != null && dateFrom.after(filterDate)) ret = false;
            if (dateTo != null && dateTo.before(filterDate)) ret = false;

        } catch (ParseException e) {
            return true;
        }

       return ret;
    }     
   
    
    public SacController() {
    }

    public Sac getSelected() {
        return selected;
    }

    public void setSelected(Sac selected) {
        this.selected = selected;
    }

    protected void setEmbeddableKeys() {
    }

    protected void initializeEmbeddableKey() {
    }

    private SacFacade getFacade() {
        return ejbFacade;
    }

    public Sac prepareCreate() {
        selected = new Sac();
        initializeEmbeddableKey();
        if (getSelectedCliente()!= null) selected.setTbInstCodInstituicao(getSelectedCliente());
        return selected;
    }

    public void create() {
        persist(PersistAction.CREATE, "Importação efetuada com sucesso");
        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public void update() {
        persist(PersistAction.UPDATE, ResourceBundle.getBundle("/Bundle").getString("SacUpdated"));
    }

    public void destroy() {
        persist(PersistAction.DELETE, ResourceBundle.getBundle("/Bundle").getString("SacDeleted"));
        if (!JsfUtil.isValidationFailed()) {
            selected = null; // Remove selection
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public String customFormatDate(Date date) {
        return JsfUtil.customFormatDate(date);
    }

    public String customFormatHour(Date date) {
        return JsfUtil.customFormatHour(date);
    }
    
    /**
     *
     * @return
     */
    public List<Sac> getItems() {
        if (selectedCliente != null) items = getFacade().findByClienteId(selectedCliente);
        else items = getFacade().findAll();
        return items;
    }

    private void persist(PersistAction persistAction, String successMessage) {
        if (selected != null) {
            setEmbeddableKeys();
            try {
                if (persistAction != PersistAction.DELETE) {
                    selected.setTbInstCodInstituicao(getSelectedCliente());
                    getFacade().edit(selected);
                } else {
                    getFacade().deletarPorID(selected.getId());
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                String msg = "";
                Throwable cause = ex.getCause();
                if (cause != null) {
                    msg = cause.getLocalizedMessage();
                }
                if (msg.length() > 0) {
                    JsfUtil.addErrorMessage(msg);
                } else {
                    JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
    }

    /**
     *
     * @param id
     * @return
     */
    public Sac getSac(java.lang.Integer id) {
        return getFacade().find(id);
    }

    /**
     *
     * @return
     */
    public List<Sac> getItemsAvailableSelectMany() {
        return getFacade().findAll();
    }

    /**
     *
     * @return
     */
    public List<Sac> getItemsAvailableSelectOne() {
        return getFacade().findAll();
    }

    public void handleFileUpload(FileUploadEvent event) {
        FacesMessage message;

        try {
            String fileName = JsfUtil.copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
            this.parseMap(JsfUtil.parseCSVLines(fileName));
            message = new FacesMessage("Arquivo importado com sucesso!", event.getFile().getFileName() + " foi importado.");
        } catch (IOException e) {
            message = new FacesMessage("Erro ao importar", e.getMessage());
        }
        FacesContext.getCurrentInstance().addMessage(null, message);

    }

    private void parseMap(List<String[]> list) {
        TbInstController clienteController = (TbInstController) FacesContext.getCurrentInstance().getApplication().getELResolver().
                getValue(FacesContext.getCurrentInstance().getELContext(), null, "tbInstController");

        ProfissaoFormacaoController profissaoFormacaoController = (ProfissaoFormacaoController) FacesContext.getCurrentInstance().getApplication().getELResolver().
                getValue(FacesContext.getCurrentInstance().getELContext(), null, "profissaoFormacaoController");
        
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        Date dataCadastro;

        TbInst cliente;

        for (String[] item : list) 
        {
            if (item.length >= 11 && item[8].contains("@")) 
            {
                cliente = clienteController.getByEmail(item[8]);

                if (cliente == null) {

                    cliente = new TbInst();
                    cliente.setNomFantasia(item[1]);
                    cliente.setDesCidade(item[2]);
                    cliente.setDesUf(item[3]);
                    cliente.setDesEmail(item[8]);
                    cliente.setDesFone1(JsfUtil.formatPhone(item[10]));
                    
                    ProfissaoFormacao profissao = profissaoFormacaoController.getByDescricao(item[6]);
                    
                    if (profissao == null)
                    {
                        profissao = new ProfissaoFormacao();
                        profissao.setDescricao(item[6]);
                        profissao.setId(0);
                        profissao.setTbInstList(new ArrayList<TbInst>());
                        
                        try
                        {
                            profissaoFormacaoController.prepareCreate();
                            profissaoFormacaoController.setSelected(profissao);
                            profissaoFormacaoController.create();
                            profissao = profissaoFormacaoController.getByDescricao(item[6]);
                        }
                        catch(Exception ex){
                            break;
                        }
                    }
                    
                    cliente.setProfissaoProfissaoId(profissao);
                    
                    clienteController.prepareCreate();
                    cliente.setDatInclusao(new Date());
                    cliente.setDesInclusao(((Usuario)JsfUtil.GetSessionParameter("user")).getLogin());
                    clienteController.setSelected(cliente);
                    clienteController.create();
                    cliente = clienteController.getByEmail(item[8]);

                }

                try {
                    dataCadastro = df.parse(item[9]);
                }
                catch(Exception ex)
                {
                    dataCadastro = new Date();
                }
                
                
                if (cliente != null && getFacade().findByClienteIdAndAssunto(cliente, item[11], dataCadastro).isEmpty()) {
                    this.prepareCreate();

                    selected.setId(0);
                    selected.setTbInstCodInstituicao(cliente);
                    selected.setDataCadastro(dataCadastro);
                    selected.setAssunto(item[11]);
                    try {
                        getFacade().edit(selected);
                        
                        if (cliente.getDatAlteracao() == null || cliente.getDatAlteracao().before(dataCadastro))
                        {
                            cliente.setNomFantasia(item[1]);
                            cliente.setDesCidade(item[2]);
                            cliente.setDesUf(item[3]);
                            cliente.setDesFone1(JsfUtil.formatPhone(item[10]));
                            cliente.setDatAlteracao(dataCadastro);
                            clienteController.setSelected(cliente);
                            clienteController.update();
                        }
                        
                    } catch (Exception ex) {}
                }
            }
        }
    }

    /**
     * @return the selectedCliente
     */
    public TbInst getSelectedCliente() {
        return selectedCliente;
    }

    /**
     * @param selectedCliente the selectedCliente to set
     */
    public void setSelectedCliente(TbInst selectedCliente) {
        this.selectedCliente = selectedCliente;
    }

    /**
     *
     */
    @FacesConverter(forClass = Sac.class)
    public static class SacControllerConverter implements Converter {

        /**
         *
         * @param facesContext
         * @param component
         * @param value
         * @return
         */
        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            SacController controller = (SacController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "sacController");
            return controller.getSac(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuilder sb = new StringBuilder();
            sb.append(value);
            return sb.toString();
        }

        /**
         *
         * @param facesContext
         * @param component
         * @param object
         * @return
         */
        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Sac) {
                Sac o = (Sac) object;
                return getStringKey(o.getId());
            } else {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), Sac.class.getName()});
                return null;
            }
        }
    }
}
